#ifndef db_MYSQLADAPTER_H
#define db_MYSQLADAPTER_H

#include "Adapter.h"
#ifdef _WIN32
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#endif

#include "MysqlConnection.h"
#include <threading/RecursiveMutex.h>


namespace serika
{
	namespace db
	{
		struct MysqlInitInfo;

		class MysqlAdapter :
			public Adapter
		{
		public:
			MysqlAdapter(const MysqlInitInfo& initInfo);
			virtual ~MysqlAdapter();

			static MysqlAdapter* NewAdapter(const Any& initInfo);
	
			virtual bool Create(const Any& initInfo);
	
			virtual void Destroy();
	
			virtual int ReadRecords(std::vector<FieldMap*>& resultSet, 
				const std::string& tableName,
				const std::string& conditions,
				int offset,
				int limit,
				const std::string& select,
				const std::string& joins,
				const std::string& order,
				const std::string& group,
				const std::string& having);
	
			virtual int Count(const std::string& tableName, const std::string& column, const std::string& conditions, const std::string& joins);
	
			virtual bool CreateRecord(FieldMap* fields, const std::string& tableName, const std::string& primaryKey);
			virtual bool CreateRecords(std::vector<FieldMap*>& fieldMaps, const std::string& tableName, const std::string& primaryKey);
	
			virtual int UpdateAllRecords(const std::string& settings, const std::string& conditions, const std::string& tableName);
	
			virtual int DeleteRecord(const std::string& conditions, const std::string& tableName);
	
			virtual void BeginTransaction();
			virtual void CommitTransaction();
			virtual void RollbackTransaction();
	
			virtual std::string EscapeString(const std::string& text);
	
		private:
			typedef Adapter Base;
			MysqlConnectionPool mPool;
			threading::RecursiveMutex mTransactionMutex;
			MysqlConnection* mTransactionConnection;
	
			inline MysqlConnection* GetConnection();
			inline void ReleaseConnection(MysqlConnection* conn);
			inline MysqlConnection* GetTransactionConnection();
			inline void ReleaseTransactionConnection();
	
			inline void ThrowRecordException(int code, const char* message);
		};
	}
}

#endif
